package KuangShen.ZhuJieHeFanShe;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

//通过反射动态的创建对象
/*
有了Class对象,能做什么？
创建类的对象：调用Class对象的newInstance()方法
前提：
    1.类必须有一个无参构造器
    2.类的构造器必须有足够的访问权限
 */
public class test09 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        //获得Class对象
        Class c1 = Class.forName("KuangShen.ZhuJieHeFanShe.User");

        //构造一个对象
        User user=(User) c1.newInstance();//本质上是调用了类的无参构造 括号的意思是c1.newInstance()构造出来的Object类型为User对象,对c1.newInstance()构造的Object起到补充的作用
        System.out.println(user);

        //通过构造器创造对象------>这种方法即使类没有无参构造也能使用
        Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
        //Object 李照垣 = constructor.newInstance("李照垣", 015, 22);<----------因为我们知道创建出来的对象是User对象，所以将Object改为User。
        User user2 = (User) constructor.newInstance("李照垣", 015, 22); //括号的意思是“constructor.newInstance("李照垣", 015, 22)"构造出来的Object类型为User对象,和强转类型差不多
        System.out.println(user2);

        //通过反射调用普通方法
        User user3 =(User)c1.newInstance();
        //通过反射获取一个方法
        Method setName = c1.getDeclaredMethod("setName", String.class);
        setName.invoke(user3,"照垣");//调用setName的invoke方法，给user3的setName方法传递一个叫“照垣”的值，invoke激活的意思----invoke(对象，“方法的值”)；如果失败可能需要关闭安全检测。
        System.out.println(user3.getName());

        //通过反射操作属性(除了方法外的就是属性)
        User user4=(User)c1.newInstance();
        Field name = c1.getDeclaredField("name");
        //开始操作name属性
        name.setAccessible(true);//<------关闭权限安全检测,否则会操作失败，因为User类的name属性是私有的,这行代码对私有属性，方法都有效。
        name.set(user4,"照垣222");
        System.out.println(user4.getName());
        /*
         */
    }
}
